package cn.hou.stream;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Stream;

import org.junit.Test;

import com.sun.org.apache.xalan.internal.utils.XMLSecurityManager.Limit;

import cn.hou.java8.Employee;

//StreamAPI
public class TestStreamAPI {
	
	//1 创建Stream
	@Test
	public void test01(){
		/**
		 * 1 创建Collections的流
		 */
		List<String> list=new ArrayList<>();
		//获取顺序流
		Stream<String> stream = list.stream();
		//获取并行流
		Stream<String> parallelStream = list.parallelStream();
		/**
		 * 2 获取数组流
		 */
		Function<Integer,Integer[]> fun=Integer[]::new;
		Integer[] nums = fun.apply(10);//lmabda创建数组
		//使用Arrays.stream() 获取数组stream流
		Stream<Integer> stream2 = Arrays.stream(nums);
		/**
		 * 3 通过Stream的静态方法of获取任意数据类型的流
		 */
		//参数可以是一个或多个任意类型的数据
		Stream<Integer> of = Stream.of(1,2,3,4,5);
		Stream<String> of2 = Stream.of("yaozhen");
		Stream<String> of3 = Stream.of("yozhen","何毅","崔杰");
		/**
		 * 4 创建无限流
		 */
		//参数是一个T类型,一个Function<T,T>接口的实现UnaryOperator<T,T>,即lambda,同类型参数返回同类型值
		Stream<Integer> iterate = Stream.iterate(0, (x)->x+2).limit(10); //.limit(10) 只获取前十个
		//无限流,会从0开始一直输入偶数,无限输出
		iterate.forEach(System.out::println);
		
		//无限生成随机数     .limit(5)取前五个
		Stream<Double> generate = Stream.generate(Math::random).limit(5).skip(2);//跳过前两个
		generate.forEach(System.out::println);
		
		
		
		
	}
	
	private List<Employee> emps = Arrays.asList(
			new Employee(102, "李四", 59, 6666.66),
			new Employee(101, "张三", 18, 9999.99),
			new Employee(103, "王五", 28, 3333.33),
			new Employee(104, "赵六", 8, 7777.77),
			new Employee(104, "赵六", 8, 7777.77),
			new Employee(104, "赵六", 8, 7777.77),
			new Employee(105, "田七", 38, 5555.55)
	);
	@Test
	public void test04(){
		//distinct:根据hascode()和equals去重,对象中需要重写方法
		emps.stream().distinct().forEach(System.out::println);
	}
	/**2 中间操作
	 * 多个中间操作可以连接起来形成一个流水线,除非流水线触发终止操作,
	 * 否则中间操作不会执行任何处理,而在终止操作时一次性全部处理,成为"惰性求值"
	 */
	@Test
	public void test02(){
		//1 筛选与切片
		Stream<Employee> stream = emps.stream().//创建流
		//filter: 接受一个断言型接口实现lambda,过滤数据,返回一个新流
		filter(e->e.getAge()<=35);
		//终止操作时 ,一次性执行中间操作
		stream.forEach(System.out::println);
	}
	@Test
	public void test03(){
		Stream<Employee> stream = emps.stream().
		filter(e->e.getSalary()>=5000)
		.skip(1)   //跳过前1个
		.limit(2);   //只取前两个,与skip合同可达到分页效果
		//终止操作时 ,一次性执行中间操作
		stream.forEach(System.out::println);
	}

}
